package v1

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm/clause"
	"net/http"
	"reflect"
	"server/common"
	"server/internal/model"
	"server/logger"
	"server/pkg/app"
)

func Search(c *gin.Context, m interface{}, list interface{}) {
	page := &app.Page{}
	page.Info(c)

	var count int64
	if err := common.DB.Debug().Model(&m).Order("id desc").Limit(page.Size).Offset((page.Page - 1) * page.Size).Find(&list).Offset(-1).Limit(-1).Count(&count).Error; err != nil {
		c.JSON(http.StatusOK, gin.H{
			"total": count,
			"data":  list,
			"msg":   err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"total": count,
		"data":  list,
	})
}

func QueryByName(m interface{}, c *gin.Context) {
	name := c.Param("name") //获取url路径中参数
	if err := common.DB.Where("name = ?", name).First(&m).Error; err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg": err.Error(),
		})
		return
	}
	return
}

func Update(m interface{}, c *gin.Context) {
	name := c.Param("name") //获取url路径中参数
	if err := common.DB.Omit(clause.Associations).Where("name = ?", name).Updates(&m).Error; err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg": err,
		})
	}
	c.String(http.StatusOK, "修改成功")
}

func Delete(m interface{}, c *gin.Context) {
	name := c.Param("name") //获取url路径中参数
	if err := common.DB.Where("name = ? or id = ?", name, name).Delete(&m).Error; err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg": err,
		})
		return
	}
	c.String(http.StatusOK, "删除成功")
}

func ShouldBind(m interface{}, c *gin.Context) {
	_ = c.Request.ParseForm()
	_ = c.ShouldBind(m)
}

func GetIp(c *gin.Context) string {
	ip := c.Request.Header.Get("X-Real-IP")
	if ip == "" {
		ip = c.Request.Header.Get("X-Forwarded-For")
	}
	if ip == "" {
		ip = c.Request.RemoteAddr
	}
	return ip
}

func CreateLog(c *gin.Context, name, desc string) {
	log := &model.Log{Name: name}
	userinfo := GetUser(c)
	log.People = userinfo.Name
	log.DESC = desc
	log.IP = GetIp(c)
	if err := common.DB.Create(&log).Error; err != nil {
		logger.Error(err.Error())
	}
}

func CreateApiLog(c *gin.Context, m interface{}, o, r string) {
	t := reflect.TypeOf(m)
	name := ""
	if t.Kind() == reflect.Struct {
		f, ok := t.FieldByName("Name")
		if ok {
			name = f.Name
		}
		method, ok := t.MethodByName("SName")
		if ok {
			result := method.Func.Call([]reflect.Value{reflect.ValueOf(&m)})
			value := reflect.ValueOf(result)
			if value.Kind() == reflect.Slice {
				element := value.Index(0)
				newStr := fmt.Sprintf("%v", element.Interface())
				log := &model.Log{Name: newStr}
				userinfo := GetUser(c)
				log.People = userinfo.Name
				log.DESC = o + newStr + name + r
				log.IP = GetIp(c)
				if err := common.DB.Create(&log).Error; err != nil {
					logger.Error(err.Error())
				}
			}
		}
	}
}
